package com.easymin.weixin.controller.v5.utils;

import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

import org.springframework.core.annotation.AnnotationUtils;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

public class JsonUtil {

	private static ObjectMapper objectMapper = null;

	static {
		objectMapper = new ObjectMapper();
		objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
		/**
		 * 通过该方法对objectMapper对象进行设置，所有序列化的对象都将按改规则进行系列化 
		 * Include.Include.ALWAYS 默认 
		 * Include.NON_DEFAULT 属性为默认值不序列化 
		 * Include.NON_EMPTY 属性为 空（""） 或者为 NULL 都不序列化 
		 * Include.NON_NULL 属性为NULL 不序列化 
		 */
		//objectMapper.setSerializationInclusion(Include.NON_NULL);
		//objectMapper.setSerializationInclusion(Include.NON_EMPTY);
	}

	/**
	 * 将对象转换成字符串
	 * 
	 * @param object 转换对象
	 * @return
	 * @throws JsonProcessingException
	 */
	public static String stringify(Object object) throws JsonProcessingException {
		return objectMapper.writeValueAsString(object);
	}

	/**
	 * 将对象转换成字符串
	 * 
	 * @param object 转换对象
	 * @param properties 转换参数
	 * @return
	 * @throws JsonProcessingException
	 */
	public static String stringify(Object object, String... properties) throws JsonProcessingException  {
		return objectMapper.writer(new SimpleFilterProvider().addFilter(AnnotationUtils.getValue(AnnotationUtils.findAnnotation(object.getClass(), JsonFilter.class)).toString(), SimpleBeanPropertyFilter.filterOutAllExcept(properties))).writeValueAsString(object);
	}

	/**
	 * 将对象通过流的方式转换成JSON字符串输出流
	 * 
	 * @param out 输出流
	 * @param object 转换对象
	 * @throws JsonGenerationException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	public static void stringify(OutputStream out, Object object) throws JsonGenerationException, JsonMappingException, IOException {
		objectMapper.writeValue(out, object);
	}

	/**
	 * 将对象通过流的方式转换成JSON字符串输出流
	 * @param out 输出流
	 * @param object 转换对象
	 * @param properties 转换参数
	 * @throws JsonGenerationException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	public static void stringify(OutputStream out, Object object, String... properties) throws JsonGenerationException, JsonMappingException, IOException {
		objectMapper.writer(new SimpleFilterProvider().addFilter(AnnotationUtils.getValue(AnnotationUtils.findAnnotation(object.getClass(), JsonFilter.class)).toString(), SimpleBeanPropertyFilter.filterOutAllExcept(properties))).writeValue(out, object);
	}

	/**
	 * 将JSON字符串转换成Map
	 * 
	 * @param json JSON串
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, ?> Parse2Map(String json) throws JsonParseException, JsonMappingException, IOException {
		return (Map<String, ?>) Parse(json, Object.class);
	}

	/**
	 * 将JSON字符串转换成List
	 * @param json JSON串
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, ?>> Parse2List(String json) throws JsonParseException, JsonMappingException, IOException {
		return (List<Map<String, ?>>) Parse(json, Object.class);
	}

	/**
	 * 将JSON字符串转换成指定对象
	 * 
	 * @param json JSON串
	 * @param clazz 指定对象类
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	public static <T> T Parse(String json, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
		if (json == null || json.length() == 0) {
			return null;
		}
		return objectMapper.readValue(json, clazz);
	}

	/**
	 * 将列表型JSON数据转换成对象列表
	 * 
	 * @param json JSON数据串
	 * @param collectionClass 接收集合类
	 * @param clazz 接收对象类
	 * @return 接收对象集合
	 * @throws IOException 
	 * @throws JsonMappingException 
	 * @throws JsonParseException 
	 */
	public static <T> List<T> Parse2List (String json, Class<?> collectionClass, Class<T> clazz) 
			throws JsonParseException, JsonMappingException, IOException {
		JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass, clazz); // 通过传入的列表类型和Bean类型，获取一个jackson的javaType
		@SuppressWarnings("unchecked")
		List<T> lst =  (List<T>) objectMapper.readValue(json, javaType);
		return lst;
	}
}
